home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
wasm223.zip
/
XMODEM2.ASM
< prev
Wrap
Assembly Source File
|
1993-05-04
|
13KB
|
432 lines
;*************************************;
; WASM Xmodem Support, File Transfers ;
; By Eric Tauck ;
; ;
; XmdUpl upload a file ;
; XmdDwn download a file ;
; ;
; Requires: ;
; ;
; BUFFER1.ASM ;
; BUFFER2.ASM ;
; BUFFER3.ASM ;
; SERIAL1.ASM ;
; STACK.ASM ;
; XMODEM1.ASM ;
;*************************************;
jmp _xmodem2_end
_XMOD_BUF EQU 4096 ;buffer size
_xmod_flg DB ? ;flags
_xmod_blk1 DW ? ;blocks transferred, low word
_xmod_blk2 DW ? ;blocks transferred, high word
_xmod_byt1 DW ? ;bytes transferred, low word
_xmod_byt2 DW ? ;bytes transferred, high word
_xmod_err DW ? ;errors
_xmod_last DB ? ;last error
;--- xmodem termination codes
XMODEM_MEMORY EQU 0 ;not enough memory
XMODEM_FILE EQU 1 ;error read or writing file
XMODEM_ABORT EQU 2 ;user abort
;========================================
; Initialize a transfer.
;
; In: CL= xmodem flags.
_xmod_init PROC NEAR
mov _xmod_flg, cl ;save flags
mov _xmod_blk1, 0 ;zero blocks
mov _xmod_blk2, 0
mov _xmod_byt1, 0 ;zero bytes
mov _xmod_byt2, 0
mov _xmod_err, 0 ;zero errors
ret
ENDP
;========================================
; Check with user.
;
; In: AL= action (0= handshake; 1=
; waiting for block; 2= waiting for
; reply).
_xmod_stat PROC NEAR
ror al
ror al
or al, _xmod_flg ;flags
mov ah, _xmod_last ;last error
mov bx, _xmod_err ;errors
mov cx, _xmod_byt1 ;byte count low
mov dx, _xmod_byt2 ;byte count high
call XmdUsr ;inform user of status
ret
ENDP
;========================================
; Process error.
;
; In: AL= error.
_xmod_error PROC NEAR
inc _xmod_err ;increment errors
mov _xmod_last, al ;save error code
ret
ENDP
;========================================
; Upload an xmodem file.
;
; In: AX= name of file; BX= serial
; record; CL= xmodem flags.
XmdUpl PROC NEAR
push bp
push di
push si
mov di, bx
StkAll bp, 1024 ;allocate xmodem data record
StkAll si, BUFFER_RECORD ;allocate file buffer record
call _xmod_init ;initialize
;--- create buffer and open file
push ax
mov ax, _XMOD_BUF ;buffer size
mov bx, si
call BufAll ;allocate buffer
pop ax
jc _xdupl3
mov bx, si
mov cl, BUFFER_READ ;access
call BufOpn ;try to open
jc _xdupl5
;--- handshake
_xdupl1 sub al, al ;action
call _xmod_stat ;update status
jc _xdupl2 ;jump if abort
mov bx, di ;serial record
mov cl, _xmod_flg ;load flags
call XmdPutH ;complete handshake
mov _xmod_flg, cl ;save flags
jnc _xdupl7 ;jump if okay
call _xmod_error ;process error
jmps _xdupl1 ;loop back
_xdupl2 jmp _xduplE ;jump if abort
;--- not enough memory
_xdupl3 mov bp, XMODEM_MEMORY
jmp _xduplF
;--- file error
_xdupl4 mov bx, si
call BufClo
_xdupl5 mov bx, si
call BufRel
mov bp, XMODEM_FILE
jmp _xduplF
;--- byte not returned reading file
_xdupl6 or _xmod_flg, XMODEM_EOF ;set EOF flag (in case not error)
or al, al ;check if EOF (error code 0)
jz _xduplA ;jump if so
pop ax ;
pop ax ;fix stack
jmps _xdupl4 ;goto error terminate
;--- read block
_xdupl7 test _xmod_flg, XMODEM_EOF ;check if end of file
jnz _xduplC ;jump if so
mov cx, 128 ;128 bytes
test _xmod_flg, XMODEM_BIG ;check if big blocks
jz _xdupl8
mov cx, 1024 ;1024 bytes
_xdupl8 push cx
push di
mov di, bp ;data buffer
;--- read/store loop
_xdupl9 mov bx, si ;input record
push cx
call GetByt ;read byte
pop cx
jc _xdupl6 ;jump if no byte returned
cld
stosb ;store byte
loop _xdupl9 ;loop
;--- done reading block
_xduplA mov dx, cx ;save bytes not written
sub al, al
cld
rep
stosb ;fill with zeros
pop di
pop ax ;restore block size
cmp ax, dx ;check if any bytes read
je _xduplC ;don't send block if not
add _xmod_blk1, 1 ;
adc _xmod_blk2, 0 ;increment block number
add _xmod_byt1, ax ;
adc _xmod_byt2, 0 ;update bytes read
;--- send block
_xduplB mov ax, bp ;block data
mov bx, di ;serial record
mov cl, _xmod_flg ;flags
mov ch, BYTE _xmod_blk1 ;block number
call XmdPut ;send block
;--- wait for reply
mov al, 1 ;action
call _xmod_stat ;update status
jc _xduplE ;jump if abort
mov bx, di ;serial record
mov cl, _xmod_flg ;flags
call XmdRep ;wait for reply
jnc _xdupl7 ;jump if okay
call _xmod_error ;process error
jmps _xduplB ;loop back
;--- send EOT
_xduplC mov al, 1 ;action
call _xmod_stat ;update status
jc _xduplE ;jump if abort
mov al, XMODEM_EOT
mov bx, di
call ComPut
;--- wait for reply
mov al, 1 ;action
call _xmod_stat ;update status
jc _xduplE ;jump if abort
mov bx, di ;serial record
mov cl, _xmod_flg ;flags
call XmdRep ;wait for reply
jnc _xduplD ;jump if okay
call _xmod_error ;process error
jmps _xduplC ;loop back
;--- finished
_xduplD mov bx, si
call BufClo ;close buffer
mov bx, si
call BufRel ;release buffer
StkRel BUFFER_RECORD + 1024 ;fix stack
pop si
pop di
pop bp
clc
ret
;--- user abort
_xduplE mov bx, si
call BufClo
mov bx, si
call BufRel
mov bp, XMODEM_ABORT
_xduplF mov ax, bp
StkRel BUFFER_RECORD + 1024 ;fix stack
pop si
pop di
pop bp
stc
ret
ENDP
;========================================
; Download an xmodem file.
;
; In: AX= name of file; BX= serial
; record; CL= xmodem flags.
XmdDwn PROC NEAR
push bp
push di
push si
mov di, bx
StkAll bp, 1024 ;allocate xmodem data record
StkAll si, BUFFER_RECORD ;allocate file buffer record
call _xmod_init ;initialize
;--- open file
push ax
mov ax, _XMOD_BUF ;buffer size
mov bx, si
call BufAll ;allocate buffer
pop ax
jc _xddwn7
mov bx, si
mov cl, BUFFER_CREATE ;access
call BufOpn ;try to open
jc _xddwn9
;--- handshake
_xddwn1 sub al, al ;action
call _xmod_stat ;update status
jc _xddwn2 ;jump if abort
mov bx, di ;serial record
mov cl, _xmod_flg ;flags
call XmdGetH ;complete handshake
jnc _xddwn3 ;jump if okay
call _xmod_error ;process error
cmp _xmod_err, 5 ;check if 5 or more timeouts
jbe _xddwn1 ;loop back if not
and _xmod_flg, NOT XMODEM_CRC ;clear CRC flag
jmps _xddwn1 ;loop back
_xddwn2 jmp _xddwnE
;--- wait for block
_xddwn3 inc _xmod_blk1 ;increment block number
jnz _xddwn4 ;jump if skip carry
inc _xmod_blk2 ;increment high word if overflow
_xddwn4 mov al, 1 ;action
call _xmod_stat ;update status
jc _xddwn2 ;jump if abort
mov ax, bp ;block data
mov bx, di ;serial record
mov cl, _xmod_flg ;flags
mov ch, BYTE _xmod_blk1 ;block number
call XmdGet ;receive block
jnc _xddwnA ;jump if okay
call _xmod_error ;process error
cmp al, XMODEM_LAST ;check if duplicated block
jne _xddwn5 ;jump if not
mov al, XMODEM_ACK ;ACK
call ComPut ;send it
jmps _xddwn4 ;loop back
_xddwn5 cmp al, XMODEM_TIME ;check if timeout
je _xddwn6 ;skip clear if so
call XmdClr ;clear pipe
_xddwn6 mov al, XMODEM_NAK ;NAK
call ComPut ;send it
jmps _xddwn4 ;loop back
;--- not enough memory
_xddwn7 mov bp, XMODEM_MEMORY
jmps _xddwnF
;--- couldn't open file
_xddwn8 pop di
mov bx, si
call BufClo
_xddwn9 mov bx, si
call BufRel
mov bp, XMODEM_FILE
jmps _xddwnF
;--- write block
_xddwnA push ax
mov al, XMODEM_ACK ;ACK
call ComPut ;send it
pop ax
cmp al, XMODEM_END ;check if end of file
je _xddwnD
mov cx, 128 ;128 bytes
cmp al, XMODEM_128 ;check 128 byte block
je _xddwnB
mov cx, 1024 ;1024 bytes
_xddwnB add _xmod_byt1, cx ;
adc _xmod_byt2, 0 ;update bytes written
push di
mov di, bp ;start of buffer
_xddwnC mov al, [di] ;load byte
inc di ;increment pointer
mov bx, si ;buffer record
push cx
call PutByt ;write byte
pop cx
jc _xddwn8 ;jump if error
loop _xddwnC ;loop for each byte
pop di
jmp _xddwn3 ;loop back for next block
;--- finished
_xddwnD mov bx, si
call BufPut ;flush buffer
mov bx, si
call BufClo ;close buffer
mov bx, si
call BufRel ;release buffer
StkRel BUFFER_RECORD + 1024 ;fix stack
pop si
pop di
pop bp
clc
ret
;--- user abort
_xddwnE mov bx, si
call BufClo
mov bx, si
call BufRel
mov bp, XMODEM_ABORT
_xddwnF mov ax, bp
StkRel BUFFER_RECORD + 1024 ;fix stack
pop si
pop di
pop bp
stc
ret
ENDP
_xmodem2_end